package com.bright.hxj.cwduijie.util;

import cn.hutool.core.util.ReUtil;
import com.bright.ghj.common.util.StringUtil;
import com.bright.hxj.cwduijie.service.AbstractApiService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.YearMonth;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * @Author hxj
 * @Date 2024/7/14 13:20
 * @Description
 */
public class CommonUtil {

    // 根据对接年份和月份构造yearMonth 注：允许只传年份和年份月份必传 若没传年份 则月份不起效
    public static String getSelectedYearMonth(Integer years, Integer months) {
        String selectedYearMonth = null;
        if (years != null) {
            selectedYearMonth = "" + years;
            if (months != null) {
                selectedYearMonth += months >= 10 ? months : "0" + months;
            }
        }
        return selectedYearMonth;
    }

    public static YearMonth getYearMonthFromKJQJString(String kjqj) {
        if (kjqj == null) return null;
        String yearString = StringUtil.substring(kjqj, 0, 4);
        String monthString = StringUtil.substring(kjqj, 4);

        return YearMonth.of(Integer.parseInt(yearString), Integer.parseInt(monthString));
    }

    // 用正则表达式获取“当前启用的会计期间是[xxxx年xx月]”的这个年月
    private static final Pattern yearMonthPattern = Pattern.compile("当前启用的会计期间是\\[(\\d{4})年(\\d+?)月\\]");
    public static YearMonth getEnableYearMonth(String writeLog) {
        String yearString = ReUtil.get(yearMonthPattern, writeLog, 1);
        String monthString = ReUtil.get(yearMonthPattern, writeLog, 2);

        return YearMonth.of(Integer.parseInt(yearString), Integer.parseInt(monthString));
    }

    // 用正则表达式获取“资产编码[xxx]在统一社会信用代码为[N24401117219426129]的组织内重复”的这个资产编码
    private static final Pattern fixedAssetRepeatCodePattern = Pattern.compile("资产编码\\[(\\S+?)\\]在统一社会信用代码为\\S+?的组织内重复");
    public static List<String> getRepeatAssetCode(String writeLog) {
        return ReUtil.getAllGroups(fixedAssetRepeatCodePattern, writeLog, false, true);
    }

    private static final Pattern usedVoucherDataKeyPattern = Pattern.compile("该科目已被会计凭证关联使用：\\[(\\S+?)\\]");
    public static List<String> getAllVoucherDataKey(String writeLog) {
        return ReUtil.getAllGroups(usedVoucherDataKeyPattern, writeLog, false, true);
    }

    // 根据凭证的dataKey获取会计期间 e.g.:202401
    private static final Pattern kjqjOfVoucherWriteLogPattern = Pattern.compile("该科目已被会计凭证关联使用：\\[\\S+?-(20\\d\\d[01]\\d)-\\S+?\\]");
    public static List<String> getKJQJFromVoucherWriteLog(String writeLog) {
        return ReUtil.getAllGroups(kjqjOfVoucherWriteLogPattern, writeLog, false, true);
    }

    private static final Pattern kjqjOfVoucherDataKeyPattern = Pattern.compile("\\S+?-(20\\d\\d[01]\\d)-\\S+?");
    public static String getKJQJFromVoucherDataKey(String voucherDataKey) {
        return ReUtil.get(kjqjOfVoucherDataKeyPattern, voucherDataKey, 1);
    }

    public static <T> T assignRandomValues(AbstractApiService<T> service) throws IllegalAccessException {
        Class<T> genericType = getGenericType(service);
        assert genericType != null;
        T bean = createInstance(genericType);

        if (bean == null) {
            throw new IllegalArgumentException("Object cannot be null");
        }

        Class<?> clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true); // 确保可以访问私有属性
            Class<?> fieldType = field.getType();

            Object randomValue = generateRandomValue(fieldType);
            try {
                field.set(bean, randomValue);
            } catch (Exception e) {
                System.out.println("设值失败：" + e.getMessage());
            }
        }
        return bean;
    }

    // 获取泛型类型的方法
    private static <T> Class<T> getGenericType(Object instance) {
        Type genericSuperclass = instance.getClass().getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            if (actualTypeArguments.length > 0) {
                Type type = actualTypeArguments[0];
                if (type instanceof Class<?>) {
                    return (Class<T>) type;
                }
            }
        }
        return null;
    }

    // 创建泛型类型对象的方法
    private static <T> T createInstance(Class<T> clazz) {
        try {
            return clazz.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Object generateRandomValue(Class<?> fieldType) {
        if (fieldType == int.class || fieldType == Integer.class) {
            return RandomUtils.nextInt(0, 1000); // 随机整数
        } else if (fieldType == long.class || fieldType == Long.class) {
            return RandomUtils.nextLong(0, 1000L); // 随机长整数
        } else if (fieldType == double.class || fieldType == Double.class) {
            double v = RandomUtils.nextDouble(0.0, 1000.0);
            return Double.valueOf(String.format("%.2f", v)); // 随机双精度浮点数
        } else if (fieldType == float.class || fieldType == Float.class) {
            return RandomUtils.nextFloat(0.0f, 1000.0f); // 随机单精度浮点数
        } else if (fieldType == boolean.class || fieldType == Boolean.class) {
            return RandomUtils.nextBoolean(); // 随机布尔值
        } else if (fieldType == String.class) {
            return RandomStringUtils.randomAlphanumeric(10); // 随机字符串
        } else if (fieldType == BigDecimal.class) {
            BigDecimal bigDecimal = BigDecimal.valueOf(RandomUtils.nextDouble(0.0, 1000.0));
            return bigDecimal.setScale(2, RoundingMode.HALF_UP);
        } else if (fieldType == Date.class) {
            return new Date();
        } else {
            // TODO 处理List类、再找找有没有漏掉的类？
            return null; // 其他类型暂时不处理
        }
    }

    public static String getRandomDataKey() {
        UUID uuid = UUID.randomUUID();
        // 改成省平台要求的格式
        return "44-" + StringUtil.right(uuid.toString(), 33);
    }
}
